package git.soulbgm;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.socket.DatagramPacket;

import java.net.InetSocketAddress;

/**
 * 通道工具类
 *
 * @author 贺瑞杰
 * @date 2020/12/28
 */
public class ChannelUtil {

    /**
     * TCP防止粘包的分隔符
     */
    private static final byte[] TCP_DELIMITER_BYTE = {120, 120, 120, 120, -120, -120, -120, -120};

    /**
     * 获得通道ID
     *
     * @param channel 通道
     * @return {@link String}
     */
    public static String getChannelId(Channel channel) {
        return channel.id().asShortText();
    }

    /**
     * 使用UDP协议发送数据
     *
     * @param channel 通道
     * @param ip      知识产权
     * @param port    港口
     * @param data    数据
     */
    public static void udpSendMsg(Channel channel, String ip, int port, byte[] data) {
        channel.writeAndFlush(new DatagramPacket(byteArrayToByteBuf(data), new InetSocketAddress(ip, port)));
    }

    /**
     * 发送数据
     *
     * @param channel 通道
     * @param data    数据
     * @return 通道异步任务结果
     */
    public static ChannelFuture tcpSendMsg(Channel channel, byte[] data) {
        if (channel == null) {
            return null;
        }
        data = byteMergerAll(data, TCP_DELIMITER_BYTE);
        return channel.writeAndFlush(byteArrayToByteBuf(data));
    }

    /**
     * 发送数据并关闭通道
     *
     * @param channel 通道
     * @param data    数据
     * @return true成功，false失败
     */
    public static void tcpSendMsgAndClose(Channel channel, byte[] data) {
        ChannelFuture future = tcpSendMsg(channel, data);
        if (future != null) {
            future.addListener(new ChannelFutureListener() {
                @Override
                public void operationComplete(ChannelFuture future) {
                    future.channel().close();
                }
            });
        }
    }

    /**
     * byte[]转ByteBuf
     *
     * @param data
     * @return
     */
    public static ByteBuf byteArrayToByteBuf(byte[] data) {
        return Unpooled.copiedBuffer(data);
    }

    /**
     * 将多个byte[]组合成一个byte[]
     *
     * @param values
     * @return
     */
    public static byte[] byteMergerAll(byte[]... values) {
        int lengthByte = 0;
        for (int i = 0; i < values.length; i++) {
            lengthByte += values[i].length;
        }
        byte[] allByte = new byte[lengthByte];

        int countLength = 0;
        for (int i = 0; i < values.length; i++) {
            byte[] b = values[i];
            System.arraycopy(b, 0, allByte, countLength, b.length);
            countLength += b.length;
        }
        return allByte;
    }

}
